package com.jerome.election.server;

import com.jerome.election.config.Config;
import com.jerome.election.config.ConfigUtil;
import com.jerome.election.constants.AppConstant;
import com.jerome.election.log.Logger;
import com.jerome.election.server.config.MemberConfig;
import com.jerome.election.server.handler.ClientHandler;
import com.jerome.election.server.paxos.Learner;
import com.jerome.election.server.paxos.ProposeAccepter;
import com.jerome.election.storage.ExpiringMap;
import com.jerome.election.sync.SyncClient;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * 系统上下文工具类
 * @author Jerome
 * @date 2023/10/18
 */
public class ContextUtil {
    /**
     * 接受者map
     */
    private static Map<Integer,SyncClient> acceptors = new HashMap<>();
    /**
     * 多数派数量
     */
    private static int majorNum;
    /**
     * 配置信息
     */
    private static MemberConfig config;
    /**
     * 日志
     */
    private static Logger logger;
    /**
     * leaner
     */
    private static Learner leaner = new Learner();

    /**
     * Proposer
     */
    private static ProposeAccepter proposeAccepter;
    /**
     * 活跃成员node
     */
    private static  ExpiringMap nodeMap = new ExpiringMap<Integer,Boolean>(15000);

    public static Learner getLeaner() {
        return leaner;
    }

    public static ProposeAccepter getProposeAccepter() {
        return proposeAccepter;
    }

    public static int getMajorNum() {
        return majorNum;
    }

    public static MemberConfig getConfig() {
        return config;
    }


    public static Map<Integer, SyncClient> getAcceptors() {
        return acceptors;
    }

    /**
     * 初始化上下文
     * @throws IOException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static void initContext() throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        //初始化acceptors
        Map<Integer, String> serverMap = getConfig().getServerMap();
        for (Map.Entry<Integer, String> entry : serverMap.entrySet()) {
            acceptors.put(entry.getKey(),new SyncClient(entry.getValue(),new ClientHandler()));
        }
        majorNum = (acceptors.size()/2+1);

        //创建日志
        logger = new Logger(config.getLogPath(),config.getLogName());
        //创建Proposer
        proposeAccepter = new ProposeAccepter("M"+config.getNode(),MemberStateEnum.getByCode(config.getRole()));
    }
    /**
     * 初始化配置
     * @param confPath 配置路基
     * @author Jerome
     * @date 2023/10/19 11:14
     */
    public static void initConf(String confPath) throws IOException, InstantiationException, IllegalAccessException {
        Properties properties = new Config(confPath).getProperties();
        MemberConfig memberConfig = ConfigUtil.build(properties, MemberConfig.class);
        //处理集群节点
        for (String key : properties.stringPropertyNames()) {
            if (key.matches(AppConstant.SERVER_REGEX)){
                memberConfig.getServerMap().put(Integer.parseInt(key.split(AppConstant.COMMA)[1]), properties.getProperty(key));
            }
        }
        config = memberConfig;
    }

    public static Logger getLogger() throws IOException {
       return logger;
    }

    public static ExpiringMap getNodeMap() {
        return nodeMap;
    }
}

